<template>
  <div v-if="visible" class="custom-drawer" :class="{ 'with-transition': isSnapping }"
       :style="{ height: drawerHeight + 'px', background: `rgba(255,255,255,${drawerBgAlpha})`, boxShadow: drawerBoxShadow }">
    <div class="drawer-drag-bar" @mousedown="startDrag" @touchstart="startDrag">
      <div class="drag-handle"></div>
    </div>
    <div class="drawer-content" :style="{ overflow: drawerContentOverflow }">
      <Search />
      <transition name="fade-scale">
        <QuickEntry v-show="showQuickEntry" :doorNum="doorNum" />
      </transition>
      <NavIntro />
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue';
import Search from '@/components/searchBottom/searchBottom.vue';
import QuickEntry from '../quickEntry/QuickEntry.vue';
import NavIntro from '../navIntro/NavIntro.vue';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  height: {
    type: Number,
    default: 350
  },
  doorNum: {
    type: [String, Number],
    required: true
  }
});

const emits = defineEmits(['update:height']);

const drawerHeight = ref(props.height || 350);
const maxHeight = ref(0);
const dragging = ref(false);
const isSnapping = ref(false);

// 计算属性
const minHeight = 80; // 只显示搜索框
const midHeight = 350; // 显示全部内容

const showQuickEntry = computed(() => drawerHeight.value > minHeight);
const drawerBgAlpha = computed(() => {
  if (drawerHeight.value >= midHeight) return 1;
  if (drawerHeight.value <= minHeight) return 0;
  return (drawerHeight.value - minHeight) / (midHeight - minHeight);
});
const drawerBoxShadow = computed(() => drawerHeight.value <= minHeight ? 'none' : '0 -2px 8px rgba(0,0,0,0.12)');
const drawerContentOverflow = computed(() => drawerHeight.value <= minHeight ? 'hidden' : 'auto');

// 生命周期
const onMounted = () => {
  maxHeight.value = window.innerHeight * 0.9;
};
onMounted();

// watch props.height
watch(
    () => props.height,
    (val) => {
      if (typeof val === 'number') drawerHeight.value = val;
    }
);

// 拖动相关方法
function getClientY(e) {
  if (e.touches && e.touches.length) {
    return e.touches[0].clientY;
  }
  return e.clientY;
}

function startDrag(e) {
  if (e.type === 'touchstart') e.preventDefault();// 禁止页面滚动
  dragging.value = true;
  isSnapping.value = false;
  document.body.style.userSelect = 'none';
  document.addEventListener('mousemove', onDrag, { passive: false });
  document.addEventListener('mouseup', stopDrag, { passive: false });
  document.addEventListener('touchmove', onDrag, { passive: false });
  document.addEventListener('touchend', stopDrag, { passive: false });
}

function onDrag(e) {
  if (e.type === 'touchmove') e.preventDefault();
  if (!dragging.value) return;
  const clientY = getClientY(e);
  let newHeight = window.innerHeight - clientY;
  newHeight = Math.max(80, Math.min(maxHeight.value, newHeight));
  drawerHeight.value = newHeight;
  emits('update:height', newHeight);
}

function stopDrag(e) {
  if (e && (e.type === 'touchend' || e.type === 'touchcancel')) e.preventDefault();
  dragging.value = false;
  document.body.style.userSelect = '';
  document.removeEventListener('mousemove', onDrag);
  document.removeEventListener('mouseup', stopDrag);
  document.removeEventListener('touchmove', onDrag);
  document.removeEventListener('touchend', stopDrag);

  // 吸附到最近的高度
  const current = drawerHeight.value;
  const snapPoints = [80, 350, maxHeight.value];
  let closest = snapPoints[0];
  let minDiff = Math.abs(current - snapPoints[0]);

  for (let i = 1; i < snapPoints.length; i++) {
    const diff = Math.abs(current - snapPoints[i]);
    if (diff < minDiff) {
      minDiff = diff;
      closest = snapPoints[i];
    }
  }

  isSnapping.value = true;
  drawerHeight.value = closest;
  emits('update:height', closest);
}
</script>

<style scoped>
.custom-drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: #fff;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.12);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  transition: none !important;
}

.custom-drawer.with-transition {
  transition: height 0.25s cubic-bezier(.4, 0, .2, 1) !important;
}

.drawer-drag-bar {
  width: 100%;
  height: 28px;
  cursor: ns-resize;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}

.drag-handle {
  width: 48px;
  height: 6px;
  background: #ccc;
  border-radius: 3px;
  margin-top: 8px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

.drawer-content {
  flex: 1;
  overflow: auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.4s;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.fade-enter-to,
.fade-leave-from {
  opacity: 1;
}

.fade-scale-enter-active,
.fade-scale-leave-active {
  transition: opacity 0.4s, transform 0.4s;
}

.fade-scale-enter-from,
.fade-scale-leave-to {
  opacity: 0;
  transform: scale(0.8);
}

.fade-scale-enter-to,
.fade-scale-leave-from {
  opacity: 1;
  transform: scale(1);
}
</style>
